using System.Collections.Generic;
using System.IO.Compression;
// using System.Net;
using System;
using System.Linq;
using UMC.SshNet;
using UMC.Web;
using UMC.Web.UI;
using UMC.Net;

namespace UMC.ITME.Activities;


[Apiumc("Proxy", "SSH", Auth = WebAuthType.User)]
class SiteSSHActivities : Web.WebActivity
{

    public static void SSHLog(Entities.Device device, string username, params string[] logs)
    {
        var file = UMC.Data.Reflection.ConfigPath($"Static\\log\\WebSSH\\{device.Ip}\\{username}.log");
        if (!System.IO.Directory.Exists(System.IO.Path.GetDirectoryName(file)))
        {
            System.IO.Directory.CreateDirectory(System.IO.Path.GetDirectoryName(file));
        }

        System.IO.File.AppendAllLines(file, logs);
    }
    public override void ProcessActivity(WebRequest request, WebResponse response)
    {
        var Key = this.AsyncDialog("Key", g =>
        {
            var form = request.SendValues ?? new WebMeta();
            var limit = form["limit"] ?? "none";

            var keys = new List<String>();
            var user = this.Context.Token.Identity();
            var searcher = UMC.Data.HotCache.Search<Entities.Device>();

            var Keyword = form["Keyword"];

            if (String.IsNullOrEmpty(Keyword) == false)
            {
                searcher.Or().Like(new Entities.Device { Caption = Keyword, Ip = Keyword, Username = Keyword, Desc = Keyword });
            }
            switch (limit)
            {
                case "PC":
                    {
                        var sts = new System.Data.DataTable();
                        sts.Columns.Add("id");
                        sts.Columns.Add("ip");
                        sts.Columns.Add("caption");
                        sts.Columns.Add("user");
                        sts.Columns.Add("port");
                        sts.Columns.Add("type");

                        var ds = searcher.Query(new Entities.Device(), false, 0, 500, out var index);
                        Utility.Each(ds, r => keys.Add($"WebSSH/{r.Id}"));

                        var auths = UMC.Security.AuthManager.Authorization(user, 0, keys.ToArray());
                        var count = 0; int i = 0;
                        foreach (var d in ds)
                        {
                            if (auths[i].Item1 > 0)
                            {
                                count++;
                                sts.Rows.Add(d.Id, d.Ip, d.Caption, d.Username, d.Port, d.Type);
                            }
                            i++;
                        }
                        var rdata = new WebMeta().Put("data", sts);

                        if (count == 0)
                        {
                            if (String.IsNullOrEmpty(Keyword))
                            {
                                rdata.Put("msg", "未有可访问的设备");
                            }
                            else
                            {
                                rdata.Put("msg", $"未搜索到“{Keyword}”相关可访问的设备");
                            }

                        }
                        var lic = UMC.Data.License.GetLicense("WebSSH", 5);

                        Data.Caches.ICacheSet cacheSet = UMC.Data.HotCache.Cache<Entities.Device>();
                        if ((cacheSet.Count > lic.Quantity && lic.Quantity > 0) || (lic.ExpireTime > 0 && lic.ExpireTime < Utility.TimeSpan()))
                        {

                            response.Redirect("System", "License", new Web.UIConfirmDialog("设备数量超限,请保持合规.")
                            {
                                Title = "版权授权",
                                DefaultValue = "WebSSH"
                            }, false);
                        }

                        this.Context.Send("WebSSH", request.IsMaster ? rdata.Put("IsMaster", true) : rdata, true);
                    }
                    break;
                default:
                    {
                        var title = UITitle.Create();

                        title.Title = "我的设备";

                        var ds = searcher.Query(new Entities.Device(), false, 0, 500, out var index);
                        Utility.Each(ds, r => keys.Add($"WebSSH/{r.Id}"));
                        var auths = UMC.Security.AuthManager.Authorization(user, 0, keys.ToArray());
                        if (request.IsMaster)
                            title.Right(new UIEventText().Icon('\ue907').Click(new UIClick(request, g, "Create")));
                        var ui = UISection.Create(title);
                        var webr = UMC.Data.WebResource.Instance();
                        var count = 0;
                        int i = 0;
                        foreach (var d in ds)
                        {
                            if (auths[i].Item1 > 0)
                            {
                                var item = new UIIconNameDesc.Item('\uf17c', d.Caption, $"{d.Username}@{d.Ip}");
                                count++;
                                UIIconNameDesc uIIcon = new UIIconNameDesc(item);
                                item.Color(0x111);
                                item.Click(new UIClick(request, g, d.Id.ToString()));
                                if (request.IsMaster)
                                {
                                    ui.Delete(uIIcon, new UIEventText("删除").Click(new UIClick(request, g, d.Id.ToString(), "Model", "Remove")));
                                }
                                else
                                {
                                    ui.Add(uIIcon);
                                }
                            }
                            i++;
                        }
                        if (count == 0)
                        {
                            if (String.IsNullOrEmpty(Keyword))
                            {
                                var desc = new UIDesc("未有可访问的设备");
                                desc.Put("icon", "\uf016").Format("desc", "{icon}\n{desc}");
                                desc.Style.Align(1).Color(0xaaa).Padding(20, 20).BgColor(0xfff).Size(12).Name("icon", new UIStyle().Font("wdk").Size(60));
                                ui.Add(desc);
                            }
                            else
                            {
                                var desc = new UIDesc($"未搜索到“{Keyword}”相关可访问的设备");
                                desc.Put("icon", "\uf016").Format("desc", "{icon}\n{desc}");
                                desc.Style.Align(1).Color(0xaaa).Padding(20, 20).BgColor(0xfff).Size(12).Name("icon", new UIStyle().Font("wdk").Size(60));
                                ui.Add(desc);
                            }
                        }
                        ui.SendTo(this.Context, true, $"{request.Model}.{request.Command}");
                    }
                    break;
            }


            return this.DialogValue("none");
        });
        switch (Key)
        {
            case "Create":
                Create();
                break;
        }
        var device = UMC.Data.HotCache.Get(new Entities.Device { Id = Utility.IntParse(Key, 0) });
        var model = this.AsyncDialog("Model", g =>
        {
            int start = UMC.Data.Utility.IntParse(request.SendValues?["start"] as string, 0);
            var nextKey = request.SendValues?["NextKey"] ?? "Header";

            UISection ui = null;
            UISection pathUI = null;
            if (start == 0 && String.Equals(nextKey, "Header"))
            {
                ui = UISection.Create(new UITitle("设备信息"));
                ui.AddCell("设备名称", device.Caption, new UIClick(request, g, "Editer"));

                var cell = UI.UI("登录地址", $"{device.Ip}:{device.Port}");

                if (request.IsMaster && request.IsApp == false)
                {
                    ui.Delete(cell, new UIEventText("删除").Click(new UIClick(request, g, "Remove")));
                }
                else
                {
                    ui.Add(cell);
                }
                ui.AddCell("用户名", device.Username);
                if (request.IsMaster)
                {
                    if (String.IsNullOrEmpty(device.Desc) == false)
                    {
                        ui.AddCell("描述", device.Desc);
                    }
                    ui.AddCell("设置权限", new UIClick("Settings", "AuthKey", new WebMeta().Put("Key", $"WebSSH/{device.Id}")));
                }
                pathUI = ui.NewSection();

            }
            else
            {
                ui = pathUI = UISection.Create();
            }
            pathUI.Key = "Path";
            var path = this.AsyncDialog("Path", "/");
            var password = UMC.Data.DataFactory.Instance().Password(SiteConfig.MD5Key(device.Ip, device.Username));
            try
            {
                using (var sftp = new SftpClient(new PasswordConnectionInfo(device.Ip, device.Port ?? 22, device.Username, password)))
                {
                    sftp.Connect();
                    var sftpFiles = sftp.ListDirectory(path).OrderByDescending(r => r.IsDirectory).Where(f => f.Name != "." && f.Name != "..");
                    if (String.Equals(path, "/"))
                    {
                        pathUI.AddCell('\uf0e8', "根目录", "/");
                    }
                    else
                    {
                        var name = path.LastIndexOf('/', path.Length - 1);
                        var parentPath = path.Substring(0, name);
                        var click = request.IsApp ? UIClick.Query("Path", new WebMeta("Path", String.IsNullOrEmpty(parentPath) ? "/" : parentPath)) : UIClick.UIEvent("Search", new WebMeta("key", "Path").Put("search", new WebMeta("Path", path.Substring(0, name))));// UIClick.Click(new UIClick(request, "Path", path.Substring(0, name), "Model", "Next"));
                        if (sftpFiles.Count() == 0)
                        {
                            var cell = UICell.Create("UI", new WebMeta("value", path.Substring(name + 1)).Put("text", "当前目录").Put("Icon", '\uf0e8').Put("click", click));
                            pathUI.Delete(cell, new UIEventText("删除").Click(UIClick.Click(new UIClick(request, g, "Del", "Path", path + "/"))));

                            var desc = new UIDesc($"当前目录没有文件或子目录");
                            desc.Put("icon", "\uf016").Format("desc", "{icon}\n{desc}");
                            desc.Style.Align(1).Color(0xaaa).Padding(20, 20).BgColor(0xfff).Size(12).Name("icon", new UIStyle().Font("wdk").Size(60));
                            pathUI.Add(desc);
                        }
                        else
                        {
                            pathUI.AddCell('\uf0e8', "当前目录", path.Substring(name + 1), click);
                        }
                    }
                    foreach (var file in sftpFiles)
                    {
                        if (file.IsDirectory)
                        {
                            pathUI.AddCell('\uf114', file.Name, "", request.IsApp ? UIClick.Query("Path", new WebMeta("Path", file.FullName)) : UIClick.UIEvent("Search", new WebMeta("key", "Path").Put("search", new WebMeta("Path", file.FullName))));// ("Path", file.FullName)));
                        }
                        else
                        {
                            var cell = UICell.Create("UI", new WebMeta("value", Utility.GetBitSize(file.Length)).Put("text", file.Name).Put("Icon", '\uf0f6').Put("click", new UIClick(request, g, file.Length > 1000000 ? "Down" : "View", "Path", file.FullName)));
                            pathUI.Delete(cell, new UIEventText("删除").Click(new UIClick(request, g, "Del", "Path", file.FullName)));
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                var desc = new UIDesc(ex.Message);
                pathUI.Add(desc);
            }
            ui.UIFootBar = new UIFootBar() { IsFixed = true };
            ui.UIFootBar.AddIcon(new UIEventText('\uf0ee', "上传").Click(new UIClick(request, g, "UploadFile")));
            ui.UIFootBar.AddText(new UIEventText("新建目录").Click(new UIClick(request, g, "New")),
             new UIEventText("终端打开").Click(new UIClick(request, g, "Open")).Style(new UIStyle().BgColor()));

            ui.SendTo($"OpenPath,UploadFile,{request.Model}.{request.Command}.Remove", this.Context, true, $"{request.Model}.{request.Command}");

        });
        var Path = this.AsyncDialog("Path", "/");
        var password = UMC.Data.DataFactory.Instance().Password(SiteConfig.MD5Key(device.Ip, device.Username));
        //
        switch (model)
        {
            case "Next":
                {
                    var webMeta = new WebMeta(request.Arguments);

                    webMeta.Remove("Model");
                    this.Context.Send("ViewPath", new WebMeta().Put("Path", Path), false);
                    this.Context.Send(new WebMeta().UIEvent("Search", this.AsyncDialog("UI", "none"), new WebMeta("key", "Path").Put("send", webMeta)), true);

                }
                break;
            case "Editer":
                {
                    var config = this.AsyncDialog("Settings", g =>
                    {
                        var from = new Web.UIFormDialog() { Title = "设备" };
                        from.AddTextValue().Put("登录地址", $"{device.Ip}:{device.Port}").Put("用户名", device.Username);

                        from.AddText("名称", "Caption", device.Caption);

                        from.AddText("描述", "Desc", device.Desc).NotRequired();//.Put("tip", String.Empty);
                        from.Submit("确认修改", $"{this.Context.Request.Model}.{this.Context.Request.Command}");
                        return from;
                    });
                    Data.HotCache.Put(new Entities.Device
                    {
                        Id = device.Id,
                        Desc = config["Desc"],
                        Caption = config["Caption"]
                    });
                    this.Context.Send($"{this.Context.Request.Model}.{this.Context.Request.Command}", true);

                }
                break;
            case "UploadFile":
                if (request.IsApp)
                {
                    request.Arguments["Model"] = "File";
                    goto case "Dir";
                }
                else
                {
                    this.Context.Send("UploadFile", new WebMeta().Put("Path", Path), true);
                }
                break;
            case "Dir":
            case "File":
                {
                    var media_id = this.AsyncDialog("media_id", g =>
                      {
                          if (request.IsApp)
                          {
                              return Web.UIDialog.Create("File");
                          }
                          else
                          {
                              var from = new Web.UIFormDialog() { Title = "上传文件" };
                              var conf = from.AddFile("选择资源", "media_id", String.Empty).Put("Accept", "*/*").Put("Multiple", true);

                              switch (model)
                              {
                                  case "Dir":
                                      from.Title = "上传文件夹";
                                      conf.Put("Dir", true);
                                      break;
                              }
                              from.Submit("确认上传");
                              return from;
                          }
                      });
                    var deviceKey = Utility.Guid(this.AsyncDialog("Device", "none"));
                    var filePath = String.Format("{0}{1}", Path, Path.EndsWith('/') ? "" : "/");
                    if (media_id.StartsWith("http://") || media_id.StartsWith("https://"))
                    {
                        var url = new Uri(media_id);
                        var name = Uri.UnescapeDataString(url.AbsolutePath.Substring(url.AbsolutePath.LastIndexOf('/') + 1));

                        url.WebRequest().Get(r =>
                        {
                            if (r.StatusCode == System.Net.HttpStatusCode.OK)
                            {
                                var tempFile = System.IO.Path.GetTempFileName();
                                var stream = System.IO.File.Open(tempFile, System.IO.FileMode.Create);

                                r.ReadAsData((b, i, c) =>
                                {
                                    if (c == 0 && b.Length == 0)
                                    {
                                        if (i == -1)
                                        {
                                            this.Prompt("Web SSH", "上传失败", false);
                                            stream.Close();
                                            System.IO.File.Delete(tempFile);
                                        }
                                        else
                                        {
                                            stream.Flush();
                                            stream.Close();
                                            try
                                            {
                                                Upload(name, filePath, tempFile, device, password, deviceKey);
                                                this.Prompt("上传成功", false);
                                            }
                                            catch (Exception ex)
                                            {
                                                this.Prompt("上传错误", ex.Message, false);
                                            }
                                        }
                                        this.Context.Send(false);
                                        this.Context.OutputFinish();
                                    }
                                    else
                                    {
                                        stream.Write(b, i, c);
                                    }
                                });
                            }
                            else
                            {

                                this.Prompt("Web SSH", "上传失败", false);
                                this.Context.OutputFinish();
                            }
                        });
                        response.Redirect(Empty);
                    }
                    else
                    {
                        media_id = Uri.UnescapeDataString(media_id);
                        var filename = UMC.Data.Reflection.ConfigPath(String.Format("Static\\TEMP\\{0}", media_id.Substring(media_id.IndexOf('/', 2) + 1)));

                        var name = media_id.Substring(media_id.LastIndexOf('/') + 1);
                        try
                        {
                            Upload(name, filePath, filename, device, password, deviceKey);
                        }
                        catch (Exception ex)
                        {
                            this.Prompt("上传错误", ex.Message);
                        }
                        this.Context.Send(true);
                    }

                }
                break;
            case "Open":
                if (request.IsApp)
                {
                    String url;
                    if (Path == "/")
                    {

                        url = new Uri(request.Url, $"/WebSSH/{device.Id}/").AbsoluteUri;
                    }
                    else
                    {
                        url = new Uri(request.Url, $"/WebSSH/{device.Id}{Path}/").AbsoluteUri;

                    }
                    var webMeta = new WebMeta();
                    webMeta.Put("value", url);
                    webMeta.Put("right", new UIEventText().Icon('\uf11c').Click(UIClick.Click(new UIClick(request, "Model", "Keyboard"))));
                    this.Context.Send("OpenUrl", webMeta, true);
                }
                else
                {
                    this.Context.Send("OpenPath", new WebMeta().Put("Path", Path), true);
                }
                break;
            case "Keyboard":
                {
                    var ui = this.AsyncDialog("UI", "none");
                    var Paste = this.AsyncDialog("PasteText", r =>
                      {
                          var s = new UISheetDialog() { Title = "快捷键" };

                          s.CloseEvent = $"{request.Model}.{request.Command}";
                          s.Cells(3);
                          s.Put(new UIClick("Event", new WebMeta().UIEvent("UI.Callback", ui, new WebMeta().Put("type", "Keyboard", "value", "\u001b"))) { Text = "ESC" });
                          s.Put(new UIClick("Event", new WebMeta().UIEvent("UI.Callback", ui, new WebMeta().Put("type", "Keyboard", "value", "\u001b[A"))) { Text = "↑" });
                          s.Put(new UIClick("Event", new WebMeta().UIEvent("UI.Callback", ui, new WebMeta().Put("type", "Keyboard", "value", "\u0003"))) { Text = "Ctrl + C" });
                          s.Put(new UIClick("Event", new WebMeta().UIEvent("UI.Callback", ui, new WebMeta().Put("type", "Keyboard", "value", "\u001b[D"))) { Text = "←" });
                          s.Put(new UIClick("CaseCMS", new UIClick(request)) { Text = "粘贴" });

                          // s.Put(new UIClick("Event", new WebMeta().UIEvent("UI.Refresh", ui, new WebMeta().Put("type", "Keyboard", "value", "\t"))) { Text = "刷新" });
                          s.Put(new UIClick("Event", new WebMeta().UIEvent("UI.Callback", ui, new WebMeta().Put("type", "Keyboard", "value", "\u001b[C"))) { Text = "→" });
                          s.Put(new UIClick("Event", new WebMeta().UIEvent("UI.Callback", ui, new WebMeta().Put("type", "Keyboard", "value", "\u001b[H"))) { Text = "Home" });
                          s.Put(new UIClick("Event", new WebMeta().UIEvent("UI.Callback", ui, new WebMeta().Put("type", "Keyboard", "value", "\u001b[B"))) { Text = "↓" });
                          s.Put(new UIClick("Event", new WebMeta().UIEvent("UI.Callback", ui, new WebMeta().Put("type", "Keyboard", "value", "\u001b[F"))) { Text = "END" });

                          return s;
                      });
                    this.Context.Send(new WebMeta().UIEvent("UI.Callback", ui, new WebMeta().Put("type", "Keyboard", "value", Paste)), true);
                }
                break;
            case "New":
                {
                    var filePath = String.Format("{0}{1}", Path, Path.EndsWith('/') ? "" : "/");
                    var dir = this.AsyncDialog("DirName", r => new UITextDialog() { Title = "新建文件夹" });
                    using (var sftp = new SftpClient(new PasswordConnectionInfo(device.Ip, device.Port ?? 22, device.Username, password)))
                    {
                        sftp.Connect();

                        sftp.CreateDirectory(filePath + dir);

                    }
                    this.Context.Send(true);
                }
                break;
            case "Download":
                response.Redirect(new Uri(request.Url, $"/WebSSH/{device.Id}{Path}"));
                break;
            case "Edit":
                this.Context.Send("Markdown", new WebMeta().Put("submit", new UIClick(request, "Model", "Content")), true);
                break;
            case "Down":
            case "View":
                this.AsyncDialog("View", r =>
                {
                    var value = UIClick.Markdown(new UIClick(request, "Model", "Content")); value.Text = "编辑";
                    var s = new UISheetDialog() { Title = "文件选择" };
                    s.Put(new UIClick(new Uri(request.Url, $"/WebSSH/{device.Id}{Path}").AbsoluteUri) { Key = "Url", Text = "下载" });
                    if (model == "View")
                        s.Put(value);
                    return s;
                });
                break;
            case "Content":
                {
                    using (var sftp = new SftpClient(new PasswordConnectionInfo(device.Ip, device.Port ?? 22, device.Username, password)))
                    {
                        sftp.Connect();
                        var Content = this.AsyncDialog("Content", r =>
                        {
                            String s = String.Empty;
                            try
                            {
                                s = sftp.ReadAllText(Path);
                            }
                            catch (Exception ex)
                            {
                                this.Prompt("打开失败", ex.Message);
                            }

                            response.Redirect(new WebMeta().Put("Content", s).Put("title", Path));

                        });
                        sftp.WriteAllText(Path, Content);

                        SSHLog(device, this.Context.Token.Username, $"upload {Path}");
                    }
                }
                break;
            case "Remove":
                {
                    UMC.Data.HotCache.Delete(new Entities.Device { Id = Utility.IntParse(Key, 0) });

                    this.Context.Send($"{request.Model}.{request.Command}.Remove", true);
                }
                break;
            case "Del":
                {
                    using (var sftp = new SftpClient(new PasswordConnectionInfo(device.Ip, device.Port ?? 22, device.Username, password)))
                    {
                        sftp.Connect();
                        if (Path.EndsWith('/'))
                        {
                            var delPath = Path.Substring(0, Path.Length - 1);
                            sftp.DeleteDirectory(delPath);
                            SSHLog(device, this.Context.Token.Username, $"rmdir {delPath}");
                            var webMeta = new WebMeta(request.Arguments);

                            webMeta.Remove("Model");

                            var nameIndex = delPath.LastIndexOf('/');
                            webMeta.Put("Path", nameIndex == 0 ? "/" : delPath.Substring(0, nameIndex));
                            this.Context.Send("ViewPath", new WebMeta().Put("Path", webMeta["Path"]), false);
                            this.Context.Send(new WebMeta().UIEvent("Search", this.AsyncDialog("UI", "none"), new WebMeta("key", "Path").Put("send", webMeta)), true);
                        }
                        else
                        {
                            sftp.Delete(Path);
                            SSHLog(device, this.Context.Token.Username, $"rm {Path}");
                        }
                    }
                }
                break;
        }
    }
    void Upload(string name, string path, string filename, Entities.Device device, string password, Guid? deviceKey)
    {
        var filePath = String.Format("{0}{1}", path, path.EndsWith('/') ? "" : "/", name);

        using (var sftp = new SftpClient(new PasswordConnectionInfo(device.Ip, device.Port ?? 22, device.Username, password)))
        {
            sftp.Connect();
            if (name.EndsWith(".umczip"))
            {

                var fs = ZipFile.OpenRead(filename).Entries;
                var fsCount = fs.Count;
                int ucount = 0;
                foreach (var f in fs)
                {
                    ucount++;
                    if (f.Length > 0)
                    {
                        var fnames = new List<String>(f.FullName.Split('/'));
                        fnames.RemoveAt(fnames.Count - 1);
                        var sbf = new System.Text.StringBuilder();
                        sbf.Append(filePath);
                        for (var i = 0; i < fnames.Count; i++)
                        {
                            if (i > 0)
                            {
                                sbf.Append('/');
                            }
                            sbf.Append(fnames[i]);
                            if (sftp.Exists(sbf.ToString()) == false)
                            {
                                sftp.CreateDirectory(sbf.ToString());
                            }
                        }

                        using (var stm = f.Open())
                        {
                            var now = Utility.TimeSpan();
                            sftp.UploadFile(stm, filePath + f.FullName, true, (v) =>
                            {
                                if (deviceKey.HasValue)
                                {
                                    var old = Utility.TimeSpan();
                                    if (old - now > 0)
                                    {
                                        Host.HttpWebSocket.Send(deviceKey.Value, UMC.Data.JSON.Serialize(new WebMeta("type", "progress", "value", $"{f.Name}({ucount}/{fsCount}) {v * 100 / ((ulong)f.Length)}%")));
                                        now = old;
                                    }
                                }
                            });
                            SSHLog(device, this.Context.Token.Username, $"upload {filePath + f.FullName}");
                        }
                    }
                }
            }
            else
            {
                using (var s = System.IO.File.OpenRead(filename))
                {
                    var now = Utility.TimeSpan();
                    sftp.UploadFile(s, filePath + name, true, (v) =>
                    {
                        if (deviceKey.HasValue)
                        {
                            var old = Utility.TimeSpan();
                            if (old - now > 0)
                            {
                                Host.HttpWebSocket.Send(deviceKey.Value, UMC.Data.JSON.Serialize(new WebMeta("type", "progress", "value", $"{name} {v * 100 / ((ulong)s.Length)}%")));
                                now = old;
                            }
                        }
                    });
                    SSHLog(device, this.Context.Token.Username, $"upload {filePath + name}");
                }
            }
            System.IO.File.Delete(filename);

        }
    }

    void Create()
    {
        if (this.Context.Request.IsMaster == false)
        {
            this.Prompt("只有管理员才能新增设备");
        }

        var config = this.AsyncDialog("Settings", g =>
        {
            var from = new Web.UIFormDialog() { Title = "新增设备" };

            from.AddText("名称", "Caption", String.Empty);
            from.AddText("地址", "Ip", String.Empty).PlaceHolder("IP地址");
            from.AddText("端口", "Port", "22");
            from.AddText("用户名", "Username", String.Empty);
            from.AddPassword("密码", "Password", String.Empty);
            from.AddText("描述", "Desc", String.Empty).NotRequired().Put("tip", String.Empty);
            from.Submit("确认新增", $"{this.Context.Request.Model}.{this.Context.Request.Command}");
            return from;
        });

        var device = new Entities.Device { Id = Utility.TimeSpan(), Ip = config["Ip"], Port = Utility.IntParse(config["Port"], 22), Username = config["Username"], Desc = config["Desc"], Caption = config["Caption"], Type = Entities.DeviceType.Linux };

        var ssh = new SshClient(device.Ip, device.Port.Value, device.Username, config["Password"]);
        try
        {
            ssh.Connect();
            ssh.Disconnect();
            UMC.Data.HotCache.Put(device);
            UMC.Data.DataFactory.Instance().Password(new Guid(Utility.MD5(device.Ip, device.Username)), config["Password"]);
            this.Prompt("新增成功", false);

        }
        catch (Exception ex)
        {
            this.Prompt("异常", ex.Message);
        }
        this.Context.Send($"{this.Context.Request.Model}.{this.Context.Request.Command}", true);
    }
}
